You know that feeling when you randomly think of an idea (probably in the middle of the night), and you feel it could be a big hit? Well, I had a similar thought, built Nomado.live in a week, and you can see the results below:
P.S. - Nomado is a travel app that gives travellers information about visas, gives them personalized itinerary and has a community where travellers can drop genuine reviews.
Nothing makes a developer happier than having users for their apps. In this article, I will share some tips to help you build better and scalable apps. My manager often says, “If your idea worked well once, see how you can improve it.” Therefore, we need to ensure our apps have a solid architecture. I will also show you how I built Nomado using just a few services from DigitalOcean and several APIs. You don’t need to over-engineer any application to make it usable and provide a good experience.
Building apps is the most exciting part of having an idea. You are excited about the tech stack you will be using and all the fancy features that you want to add. But you need to take a step back here and think about these things first:
The use case you are solving - In my case, I wanted to build a travel app. The problem statement stemmed from my use case of having visa-related issues. I didn’t think of catering to 500 users while building the app; I thought about one user (me) and the use case that I wanted to solve for myself. Then I recalled conversations that I had with some of my friends who love to travel and the issues they face (real reviews and itineraries), so I prioritized three features and then moved to how I wanted to build it.
The application flow - Choose any tool of your choice (Excalidraw in my case), and chart out a basic flow/structure of how you want your application to look. What you see below is the first version of Nomado that I drew, and then there’s the final version now. It looks different, but the features are the same. This helped me have a design in mind and proceed step by step, later improving the experience and the design language.
Once you have fixed all of these, you then move to building the application.
Before we get into the details of “how”, let’s learn a little bit of “why” I built Nomado - I travel a lot, and my main issue is with visas (the lengthy processes, the time taken for research, and juggling between poorly made embassy websites). I needed an application that gives me all the visa-related details I need, along with an itinerary that is actually good and tells me all the must-haves, like the apps to install and things to pack, etc. Another problem is that I have been to Instagram-famous places (thanks to social media) and had a bad experience, so I wanted real feedback about places from real people. What better way to do this than by having a community section (my inner DevRel kicked in while building this)?
This is what the overall architecture of Nomado looks like:
Now let’s cover how I built the fundamentals of Nomado, and this is something that you can replicate in any application that you are building.
P.S. - The code is open source, so you can find everything on GitHub.
In Nomado, the GenAI agent is helping us with the itinerary and important tips, as shown in the image below.
The flow of the agent is pretty straightforward:
The diagram below explains exactly how the GenAI agent is working and providing us with the details:
To have a similar agentic workflow in your application, follow the steps below:
To create a GenAI agent similar to Nomado’s, you’ll need to:
For detailed step-by-step instructions on setting up your GenAI agent, follow this guide.
Once your agent is set up, let’s integrate it with your application.
To integrate the agent with your application:
Set up environment variables:
SECURE_AGENT_KEY=your_agent_key
AGENT_BASE_URL=your_agent_base_url
Initialize the OpenAI SDK:
client = new OpenAI({ apiKey: SECURE_AGENT_KEY, baseURL: AGENT_BASE_URL,});
Create your prompt structure:
const prompt = Your prompt;
Make the API call:
response = await client.chat.completions.create({ model: "Llama 3.3 Instruct", messages: [ { role: "system", content: "You are an assistant...", }, { role: "user", content: prompt }, ], temperature: 0.7, max_tokens: 2000,});
Nomado has a community section where travellers can add reviews/feedback of the countries they have visited.
I have used Postgres as a database for this, and that’s typically because:
Remember: Our aim is to make our application scalable, so this is a great step towards it.
Setting up a database on DigitalOcean is straightforward:
Once the database is provisioned, you will get the following details which are needed to establish the connection:
To connect the database to your application (Next.js in this example), you need to create a simple database utility that handles connections and queries.
Here’s how it works:
POSTGRES_HOST=your_host_url
POSTGRES_PORT=your_port
POSTGRES_USER=your_username
POSTGRES_PASSWORD=your_password
POSTGRES_DATABASE=your_database_name
import { Pool } from "pg"
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }
})
CREATE TABLE experiences (
id SERIAL PRIMARY KEY,
country VARCHAR(100) NOT NULL,
experience TEXT NOT NULL,
user_name VARCHAR(100) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
)
async function addExperience(country: string, experience: string, userName: string) {
const result = await pool.query(
"INSERT INTO experiences (country, experience, user_name) VALUES ($1, $2, $3) RETURNING *",
[country, experience, userName]
)
return result.rows[0]
}
The beauty of using Postgres with Next.js is that you can easily add more features later. For example, we added content moderation by simply adding a new column to our table:
ALTER TABLE experiences
ADD COLUMN moderation_passed BOOLEAN DEFAULT FALSE
This setup gives us a solid foundation for building more features while keeping our code clean and maintainable. Plus, with DigitalOcean’s managed database, we don’t have to worry about database maintenance or backups - it’s all handled for us.
Once your application has some structure to it, and you want to test it on production, you should consider hosting it. This too can be done in DigitalOcean using the App Platform.
Since our code is already on GitHub, we will be using it to deploy the app using the following steps:
Deploy using GitHub
/frontend
in our case)Configure resources
POSTGRES_HOST=your_db_host
POSTGRES_PORT=your_db_port
POSTGRES_USER=your_db_user
POSTGRES_PASSWORD=your_db_password
POSTGRES_DATABASE=your_db_name
SECURE_AGENT_KEY=your_genai_key
AGENT_BASE_URL=your_genai_url
If any new environment variables needs to be added, so you can do so from the Settings
page as shown below:
Once the deployment is complete, your app will be hosted on a URL like https://your-app-name.ondigitalocean.app
.
Mapping to custom domain once your app is deployed:
A custom domain is not only easier to remember, but it also helps with SEO. If you have a domain purchased (from any provider of your choice), you can map it from the control panel itself by following the steps mentioned in this tutorial.
Now your application is live with:
The best part is that you can focus on building features while DigitalOcean handles the infrastructure. When you push changes to GitHub, they’re automatically deployed to your production environment.
Building Nomado taught me a lot about building scalable applications without overcomplicating things.
Here are some key takeaways if you would like to build something similar:
P.S. - If you’re interested in seeing how Nomado works under the hood, check out the open-source code on GitHub. Feel free to use it as a reference for your own projects!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!